package lion.framework.core.web.request.multi;

import java.io.File;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;

import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.FileUploadException;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
import org.apache.commons.lang.ArrayUtils;

import lion.framework.core.util.AppPaths;

/**
 * @author Helin
 * @date 2011-4-27
 */
public class UploadRequestParser {

	private Map<String, String[]> formFieldMap = new HashMap<>();
	private Map<String, FileItem[]> uploadFileMaps = new HashMap<>();

	public UploadRequestParser(HttpServletRequest request) throws FileUploadException {

		if (!ServletFileUpload.isMultipartContent(request)) { return; }

		DiskFileItemFactory fif = new DiskFileItemFactory();
		fif.setRepository(new File(AppPaths.TEMPDIR));
		ServletFileUpload sfu = new ServletFileUpload(fif);
		sfu.setHeaderEncoding(request.getCharacterEncoding());

		// size
		List<FileItem> items = sfu.parseRequest(request);

		Map<String, List<String>> values = new HashMap<>();
		Map<String, List<FileItem>> diskFiles = new HashMap<>();
		for (FileItem fi : items) {
			if (fi.isFormField()) {
				List<String> tmp = values.get(fi.getFieldName());
				if (tmp == null) {
					tmp = new ArrayList<>();
					values.put(fi.getFieldName(), tmp);
				}
				try {
					tmp.add(fi.getString(request.getCharacterEncoding()));
				} catch (UnsupportedEncodingException e) {
				}
			} else {
				if (fi.getSize() > 0) {
					List<FileItem> FileItems = diskFiles.get(fi.getFieldName());
					if (FileItems == null) {
						FileItems = new ArrayList<>();
						diskFiles.put(fi.getFieldName(), FileItems);
					}
					FileItems.add(fi);
				}
			}
		}

		for (String key : values.keySet()) {
			formFieldMap.put(key, values.get(key).toArray(new String[0]));
		}

		for (String key : diskFiles.keySet()) {
			uploadFileMaps.put(key, diskFiles.get(key).toArray(new FileItem[0]));
		}
	}

	public String[] getParameterValues(String fieldName) {

		return formFieldMap.get(fieldName);
	}

	public Map<String, String[]> getParameterValuesMap() {

		return formFieldMap;
	}

	public String getParameter(String key) {

		String result = null;
		String[] paramStrings = formFieldMap.get(key);
		if (paramStrings != null) {
			if (paramStrings.length == 1) {
				result = paramStrings[0];
			} else if (paramStrings.length > 1) {
				result = ArrayUtils.toString(paramStrings);
			}
		}

		return result;
	}

	public Map<String, String> getParameters() {

		Map<String, String> result = new HashMap<>();

		for (String key : formFieldMap.keySet()) {
			String[] tmp = formFieldMap.get(key);
			if (tmp != null) {
				if (tmp.length == 1) {
					result.put(key, tmp[0]);
				} else if (tmp.length > 1) {
					result.put(key, ArrayUtils.toString(tmp));
				}
			}
		}
		return result;
	}

	public FileItem[] getFileItems(String fieldName) {

		return uploadFileMaps.get(fieldName);
	}

	public FileItem getFileItem(String fieldName) {

		FileItem result = null;
		if (uploadFileMaps.containsKey(fieldName)) {
			result = uploadFileMaps.get(fieldName)[0];
		}
		return result;
	}

	public List<FileItem> getUploadFileItems() {

		List<FileItem> FileItems = new ArrayList<>();
		for (FileItem[] items : uploadFileMaps.values()) {
			for (FileItem item : items) {
				FileItems.add(item);
			}
		}
		return FileItems;
	}

	public void cleanUp() {

		for (FileItem item : this.getUploadFileItems()) {
			if (!item.isInMemory()) {
				item.delete();
			}
		}
	}

	public Enumeration<String> getParameterNames() {

		return Collections.enumeration(formFieldMap.keySet());
	}
}
